package com.ch.dao;

import com.ch.util.DBUtill;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

public class BaseDao {

    /**
     * 通用的增删改
     * @param sql 执行的SQL语句
     * @param params SQL语句中的参数值
     * @return 返回受影响的行数
     * @throws Exception 异常时抛出
     */
    public int executeUpdate(String sql, Object...params) throws Exception {
        Connection connection = DBUtill.getConnection();

        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        if(params != null && params.length > 0){
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i+1, params[i]);
            }
        }
        int row = preparedStatement.executeUpdate();

        preparedStatement.close();
        if(connection.getAutoCommit()){
            DBUtill.release();
        }
        return row;
    }

    /**
     * 执行查询操作，返回结果集列表
     * @param clazz 结果对象的 Class 对象
     * @param sql 要执行的 SQL 查询语句
     * @param params SQL 查询语句中的参数值
     * @return 返回查询结果的对象列表
     * @param <T> 泛型类型，表示结果对象的类型
     * @throws Exception 执行数据库查询操作时出现的异常
     */
    public <T> List<T> executeQuery(Class<T> clazz, String sql, Object...params) throws Exception{
        Connection connection = DBUtill.getConnection();

        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        if(params != null && params.length > 0){
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i+1, params[i]);
            }
        }

        ResultSet resultSet = preparedStatement.executeQuery();
        ResultSetMetaData metaData = resultSet.getMetaData();
        int columnCount = metaData.getColumnCount();

        List<T> list = new ArrayList<>();

        while(resultSet.next()){
            T t = clazz.getDeclaredConstructor().newInstance();

            for (int i = 0; i < columnCount; i++) {
                Object value = resultSet.getObject(i);
                String fieldName = metaData.getColumnLabel(i);
                Field field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                field.set(t, value);
            }
            list.add(t);
        }
        resultSet.close();
        preparedStatement.close();
        if(connection.getAutoCommit()){
            DBUtill.release();
        }
        return list;
    }

    /**
     *  执行查询操作，返回单个结果对象
     * @param clazz 结果对象的 Class 对象
     * @param sql 要执行的 SQL 查询语句
     * @param prams SQL 查询语句中的参数值
     * @return 返回查询结果的单个对象
     * @param <T> 泛型类型，表示结果对象的类型
     * @throws Exception 执行数据库查询操作时出现异常
     */
    public <T> T executeQueryBean(Class<T> clazz, String sql, Object...prams) throws Exception {
        List<T> ts = this.executeQuery(clazz, sql, prams);
        if(ts == null && ts.size() == 0){
            return  null;
        }
        return ts.get(0);
    }
}
